/*
======================================================================
list.c

Generic linked list operations.

Ernie Wright  17 Sep 00
======================================================================
*/

#include <stdio.h>
#include <stdlib.h>
#include "lwo2.h"


/*
======================================================================
lwListFree()

Free the items in a list.
======================================================================
*/
void lwListFree(void *list, void (*freeNode) (void *))
{
	lwNode         *node, *next;

	node = (lwNode *) list;
	while(node)
	{
		next = node->next;
		freeNode(node);
		node = next;
	}
}


/*
======================================================================
lwListAdd()

Append a node to a list.
======================================================================
*/
void lwListAdd(void **list, void *node)
{
	lwNode         *head, *tail;

	head = *((lwNode **) list);
	if(!head)
	{
		*list = node;
		return;
	}
	while(head)
	{
		tail = head;
		head = head->next;
	}
	tail->next = (lwNode *) node;
	((lwNode *) node)->prev = tail;
}


/*
======================================================================
lwListInsert()

Insert a node into a list in sorted order.
======================================================================
*/
void lwListInsert(void **vlist, void *vitem, int (*compare) (void *, void *))
{
	lwNode        **list, *item, *node, *prev;

	if(!*vlist)
	{
		*vlist = vitem;
		return;
	}

	list = (lwNode **) vlist;
	item = (lwNode *) vitem;
	node = *list;
	prev = NULL;

	while(node)
	{
		if(0 < compare(node, item))
			break;
		prev = node;
		node = node->next;
	}

	if(!prev)
	{
		*list = item;
		node->prev = item;
		item->next = node;
	}
	else if(!node)
	{
		prev->next = item;
		item->prev = prev;
	}
	else
	{
		item->next = node;
		item->prev = prev;
		prev->next = item;
		node->prev = item;
	}
}
